package cc.wangzijie.ddns.aliyun.client.utils;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.alidns.model.v20150109.DescribeDomainRecordsRequest;
import com.aliyuncs.alidns.model.v20150109.DescribeDomainRecordsResponse;
import com.aliyuncs.alidns.model.v20150109.UpdateDomainRecordRequest;
import com.aliyuncs.alidns.model.v20150109.UpdateDomainRecordResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.profile.DefaultProfile;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author wangzijie
 */
@Slf4j
@Component
public class AliyunDnsUtil {

    public static void updateDdns(String domainName, String newValue) {
        log.info("========[ DDNS UPDATE START ]========");
        List<DdnsRecord> records = describeDomainRecords(domainName);
        for ( DdnsRecord record : records ) {
            if (!Objects.equals(record.getValue(), newValue)) {
                updateDomainRecord( record, newValue );
            }
        }
        log.info("========[ DDNS UPDATE END ]========\n\n");
    }

    private static final DefaultProfile PROFILE = DefaultProfile.getProfile("cn-qingdao", AccessKey.ID, AccessKey.SECRET);
    private static final IAcsClient CLIENT = new DefaultAcsClient(PROFILE);

    public static List<DdnsRecord> describeDomainRecords(String domainName) {
        DescribeDomainRecordsRequest request = new DescribeDomainRecordsRequest();
        request.setDomainName(domainName);

        List<DdnsRecord> ddnsRecords = new ArrayList<>();
        try {
            DescribeDomainRecordsResponse response = CLIENT.getAcsResponse(request);
            log.info("describeDomainRecords Response: \n{}", new Gson().toJson(response));
            List<DescribeDomainRecordsResponse.Record> records = response.getDomainRecords();
            for (DescribeDomainRecordsResponse.Record record : records) {
                DdnsRecord ddnsRecord = DdnsRecord.newInstance(record);
                ddnsRecords.add(ddnsRecord);
            }
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            log.error("ErrCode:" + e.getErrCode());
            log.error("ErrMsg:" + e.getErrMsg());
            log.error("RequestId:" + e.getRequestId());
        }
        return ddnsRecords;
    }

    public static void updateDomainRecord(DdnsRecord ddnsRecord, String newValue) {
        UpdateDomainRecordRequest request = new UpdateDomainRecordRequest();
        request.setRecordId(ddnsRecord.getRecordId());
        request.setRR(ddnsRecord.getRr());
        request.setType(ddnsRecord.getType());
        request.setValue(newValue);

        try {
            UpdateDomainRecordResponse response = CLIENT.getAcsResponse(request);
            log.info("updateDomainRecord Response: \n{}", new Gson().toJson(response));
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (ClientException e) {
            log.error("ErrCode:" + e.getErrCode());
            log.error("ErrMsg:" + e.getErrMsg());
            log.error("RequestId:" + e.getRequestId());
        }
    }
}
